#include <ChannelLog.h>
#include <csp_debug.h>
#include <csp_macros.h>
#include <csp_shared_types.h>
#include <csp_protocol_msg.h>

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <Channel.h>
#include <pthread.h>
#include <map>

using namespace std;


ChannelLog::ChannelLog()
{
	if( pthread_mutex_init(&chan_log_lock, NULL) ){
		perror("channel log could not init lock.");
		exit(-1);
	}
	//log = (char*) calloc(MAX_SIZE, sizeof(char));
	log = (log_item_t*) calloc(MAX_CH_LOG_SIZE, sizeof(log_item_t));
	i=0;
}

ChannelLog::~ChannelLog()
{
}

void ChannelLog::Print()
{
	int t;
	for(t=0; t <= i; t++){

		printf("pid=%i, op=%c, chan_id=%lx, size=%i, %s\n",
				log[t].pid, log[t].op, log[t].chan_id, (int)log[t].size,
				log[t].put ? "put" : "take");

		//printf("%d ", (int) log[t]);
	}
}


void ChannelLog::Increment(ProcessComposition* p, long channel_id, char op)
{
	pthread_mutex_lock (&chan_log_lock);
	if(MAX_CH_LOG_SIZE != i){
		log[i+1].chan_id = channel_id;
		log[i+1].pid = p->GetPID();
		log[i+1].op = op;
		log[i+1].put = true;
		log[i+1].size = log[i].size+1;
		i++;
	}
	pthread_mutex_unlock (&chan_log_lock);
}


void ChannelLog::Decrement(ProcessComposition* p, long channel_id, char op)
{
	pthread_mutex_lock (&chan_log_lock);
	if(MAX_CH_LOG_SIZE != i){
	log[i+1].chan_id = channel_id;
	log[i+1].pid = p->GetPID();
	log[i+1].op = op;
	log[i+1].put = false;
	log[i+1].size = log[i].size-1;
	i++;
	}
	pthread_mutex_unlock (&chan_log_lock);
}




ChannelLog* ChannelLog::pinstance = 0;// initialize pointer

	ChannelLog* 
ChannelLog::Instance () 
{
	if (pinstance == 0)  // is it the first call?
	{  
		pinstance = new ChannelLog(); // create sole instance
	}
	return pinstance; // address of sole instance
}


